import shutil
import tkinter as tk
from tkinter import *
from tkinter import ttk
import tkinter.ttk
import json
from tkinter.messagebox import showwarning
import requests
from openpyxl import Workbook
import os
import sys
import fnmatch
import subprocess
import time

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# 调整为SW_HIDE，表示创建的进程窗口在显示时不会激活
startupinfo.wShowWindow = subprocess.SW_HIDE

# 取得路径
def app_path():
    if hasattr(sys, 'frozen'):  # 可执行文件走这里
        return os.path.abspath(sys.executable)
    return os.path.abspath(__file__)  # 源码走这里

module_link_list = [[],[],[]] #模块，飞书链接，SVN地址

# 界面作成
window = tk.Tk()
window.geometry("300x180+600+400")
window.title("飞书同步SVN")
token_get = StringVar(value="")
SVNfoldername_Get = StringVar(value="")
SVNlog_Get = StringVar(value="")

# account_get = StringVar(value="")
# password_get = StringVar(value="")

notebook = ttk.Notebook(window)
# page1
page1 = ttk.Frame(notebook)
notebook.add(page1, text="           showlog打tag           ")
SVNfoldername = tk.Label(page1, text="文件夹名:")
SVNfoldername.place(x=10, y=30, anchor="w")
SVNfoldernameGet_before = tk.Entry(page1, width=30, textvariable=SVNfoldername_Get)
SVNfoldernameGet_before.place(x=75, y=30, anchor="w")
SVNlog = tk.Label(page1, text="SVN log:")
SVNlog.place(x=10, y=70, anchor="w")
SVNlogGet_before = tk.Text(page1, height = 3, width=25)
SVNlogGet_before.place(x=75, y=80, anchor="w")

progressbar_1 = tkinter.ttk.Progressbar(page1, length=140)
progressbar_1.place(x=75, y=115)
progressbar_1["maximum"] = 100.00001
label_bar_1 = tk.Message(page1, width=40, text="0.00%")
label_bar_1.place(x=10, y=115)

def start_1():
    SVNfoldername = SVNfoldername_Get.get()
    SVNlog = SVNlogGet_before.get("1.0", tk.END)
    tag_Creat(SVNfoldername, SVNlog)

start_botton = tk.Button(page1, text="start", width=8, command=start_1)
start_botton.place(x=225, y=113)

# page2
page2 = ttk.Frame(notebook)
notebook.add(page2, text="             飞书同步SVN             ")
token = tk.Label(page2, text="token:")
token.place(x=10, y=40, anchor="w")
tokenGet_before = tk.Entry(page2, width=35, textvariable=token_get)
tokenGet_before.place(x=60, y=40, anchor="w")

# account = tk.Label(window, text="svn账号:")
# account.place(x=10, y=60, anchor="w")
# accountGet_before = tk.Entry(window, width=35, textvariable=account_get)
# accountGet_before.place(x=70, y=60, anchor="w")

# password = tk.Label(window, text="密码:")
# password.place(x=10, y=90, anchor="w")
# passwordGet_before = tk.Entry(window, width=35, textvariable=password_get)
# passwordGet_before.place(x=70, y=90, anchor="w")

progressbar = tkinter.ttk.Progressbar(page2, length=140)
progressbar.place(x=60, y=85)
progressbar["maximum"] = 100.00001
label_bar = tk.Message(page2, width=40, text="0.00%")
label_bar.place(x=10, y=85)

# 将Notebook放入根窗口
notebook.pack(expand=1, fill="both")

def start():
    user_access_token = token_get.get()
    # error文件建立
    link_Get(str(user_access_token))

start_botton = tk.Button(page2, text="start", width=8, command=start)
start_botton.place(x=220, y=83)


def tag_Creat(SVNfoldername, SVNlog):
    label_bar_1["text"] = str(0.00) + "%"
    repo_url = "http://10.168.140.154/svn/BEV_Step3/01.SIM/04.SoftwareDevelopLibrary"
    tag_path = "http://10.168.140.154/svn/BEV_Step3/01.SIM/03.SoftwareBaselineLibrary"
    # repo_url = "http://10.1.55.19/svn/FTL_21MM_CODE/04.SoftwareDevelopLibrary/04.other/luxuelinshiyong/04.SoftwareDevelopLibrary" # 调试用
    # tag_path = "http://10.1.55.19/svn/FTL_21MM_CODE/04.SoftwareDevelopLibrary/04.other/luxuelinshiyong/03.SoftwareBaselineLibrary" # 调试用
    process = subprocess.run(['svn', 'list', repo_url], stdout=subprocess.PIPE, text=True, startupinfo=startupinfo)
    try: 
        subprocess.check_output(["svn", "mkdir", tag_path + "/" + SVNfoldername, "-m", ""], startupinfo=startupinfo) 
    except:
        print(showwarning(title="warning", message="SVN仓库中已有该文件夹，请重新输入文件夹名"))
        return
    directories = process.stdout.split()  # 将输出分割成目录列表
    schedule = len(directories)
    for directory in directories:
        # print(directory)
        if not "99.Other" in directory and not "HALI-CECH" in directory and not "XXX-HAL" in directory:
            old_svnlink = str(repo_url + "/" + directory.replace("/", ""))
            new_svnlink = str(tag_path + "/" + SVNfoldername + "/" + directory.replace("/", ""))
            try:
                subprocess.check_output(['svn', 'copy', old_svnlink, new_svnlink, "-m", SVNlog], stderr=subprocess.STDOUT, startupinfo=startupinfo)
            except subprocess.CalledProcessError as e:
                with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
                    f.write("tag created failure------" + str(e) + '\n')
        progressbar_1.step(float(1 / schedule) * 100)
        label_bar_1["text"] = str(round(progressbar_1["value"], 1)) + "%"
        window.update()
        time.sleep(0.05)


# 删除并新建SVN文件夹
def svn_Delete_Add(svn_link):
    if "http://10.168.140.154/svn/BEV_Step3/01.SIM/04.SoftwareDevelopLibrary/" in svn_link:
    # if "http://10.1.55.19/svn/FTL_21MM_CODE/04.SoftwareDevelopLibrary/04.other/luxuelinshiyong/04.SoftwareDevelopLibrary/" in svn_link: # 调试用
        try:
            subprocess.check_output(["svn", "delete", svn_link, "-m", ""], startupinfo=startupinfo)
            print("文件夹删除成功！------" + svn_link)
        except subprocess.CalledProcessError as e:
            with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
                f.write("Folder deletion failure------" + str(e) + '\n')
        
        # try:
        #     subprocess.check_output(["svn", "mkdir", svn_link, "-m", ""])
        #     print("文件夹新增成功！------" + svn_link)
        # except subprocess.CalledProcessError as e:
        #     print("文件删除失败：", e)
    else:
        with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
            f.write("The SVN path is incorrect and the folder is not deleted------" + svn_link + '\n')

# 上传到SVN
def svn_Import(folder_path, svn_link):
    # 检查文件是否存在
    # if not os.path.isfile(file_path):
    #     print(file_path + "文件不存在！")
    #     return
    
    # 上传文件到 SVN 仓库
    if "http://10.168.140.154/svn/BEV_Step3/01.SIM/04.SoftwareDevelopLibrary/" in svn_link:
    # if "http://10.1.55.19/svn/FTL_21MM_CODE/04.SoftwareDevelopLibrary/04.other/luxuelinshiyong/04.SoftwareDevelopLibrary/" in svn_link: # 调试用    
        try:
            subprocess.check_output(["svn", "import", folder_path, svn_link, "-m", ""], startupinfo=startupinfo)
            print("文件夹上传成功！------" + svn_link)
        except subprocess.CalledProcessError as e:
            with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
                f.write("Folder upload failure------" + str(e) + '\n')
    else:
        with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
            f.write("The SVN path is incorrect and no folder is uploaded------" + svn_link + '\n')
            
# 文件下载
def file_Down(user_access_token, module, svn_link, father_name, child_link):
    headers = {
        'Authorization': "Bearer "+ user_access_token
        }
    if "https://neusoft.feishu.cn/file/" in child_link:
        token = str(child_link).replace('https://neusoft.feishu.cn/file/','')
        try:
            token = token[:(token.index('?'))]
        except:
            token = token
        url='https://open.feishu.cn/open-apis/drive/v1/files/'+ token + '/download'
        try:
            response = requests.request("GET", url, headers=headers)
        except:
            with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
                f.write("File not download, requests.exceptions.ChunkedEncodingError------" + module + "\\" + father_name + "::" + child_link + '\n')
            return
    # elif "https://neusoft.feishu.cn/sheets/" in child_link:
    #     token = str(child_link).replace('https://neusoft.feishu.cn/sheets/','')
    #     try:
    #         token = token[:(token.index('?'))]
    #     except:
    #         token = token
    #     url='https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/'+ token + '/download'
    #     response = requests.request("GET", url, headers=headers)
    else:
        with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
            f.write("File not download------" + module + "\\" + father_name + "::" + child_link + '\n')
        return

    # 中间文件建立
    wb = Workbook()
    wb.save(str(os.path.dirname(app_path())) + "\\" + module + "\\"+ father_name)
    file_loc = str(os.path.dirname(app_path())) + "\\" + module + "\\" + father_name
    # print(file_loc)
    # print(child_link)
    with open(file_loc, 'wb') as f:
        f.write(response.content)

    # svn_url = svn_link + "/" + str(father_name).replace("\\","/")
    # print(svn_url)
    # svn_Import(file_loc, svn_url)


# 文件空间list取得
def fileFolder_Get(user_access_token, module, svn_link, father_name, child_link):
    headers = {
        'Authorization': "Bearer "+ user_access_token
    }
    token = str(child_link).replace('https://neusoft.feishu.cn/drive/folder/','')
    try:
        token = token[:(token.index('?'))]
    except:
        token = token
    url='https://open.feishu.cn/open-apis/drive/v1/files?direction=DESC&order_by=EditedTime&folder_token='+ token
    response = requests.request("GET", url, headers=headers)
    json_Data = json.loads(response.text)
    # print(json_Data)
    # try:
    folderPath = json_Data['data']['files']
    for item in folderPath:
        mid_child_name = item['name']
        mid_child_link = item['url']
        if not fnmatch.fnmatch(father_name, ""):
            mid_father_name = father_name + "\\" + mid_child_name
        else:
            mid_father_name = mid_child_name
        # print(mid_father_name)
        # print(mid_child_link)
        link_class(user_access_token, module, svn_link, mid_father_name, mid_child_link)
    # except:
    #     print(mid_father_name + "::" + child_link + "：文件空间有错误")

# 本地新建文件夹
def folder_Set(module, father_name):
    # folder_path = str(os.path.dirname(app_path())) + "\\" + module
    # if not os.path.exists(folder_path):
    #     os.mkdir(folder_path)
    # else:
    #     pass

    folder_path = str(os.path.dirname(app_path())) + "\\" + module + "\\" + father_name
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
    else:
        pass

# 对链接进行分类
def link_class(user_access_token, module, svn_link, father_name, child_link):
    if 'https://neusoft.feishu.cn/drive/folder/' in child_link:
        # if not fnmatch.fnmatch(father_name, ""):
        folder_Set(module, father_name)
        # else:
            # pass
        fileFolder_Get(user_access_token, module, svn_link, father_name, child_link)
    # elif 'https://neusoft.feishu.cn/file/' in child_link:
    #     file_Down(user_access_token, module, svn_link, father_name, child_link)
    else:
        file_Down(user_access_token, module, svn_link, father_name, child_link)
    
def link_Get(user_access_token):
    # 获取多维表格数据
    sheet_token="WWpdsZwQahU0Yotfyahcdas5noe" 
    # sheet_token="MS0jsQVOOhsdc0toK1Oc87eTndh" # 调试用
    feishu_ranges = "C:F"

    mid_module = ''
    module = ''
    svn_link = ''
    feishu_link = ''
    try:
        url = "	https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/" + sheet_token + "/sheets/query"
        Authorization_value="Bearer "+ user_access_token
        headers = {
            'Authorization': Authorization_value
            }
        response = requests.request("GET", url, headers=headers)
        json_Data = json.loads(response.text)
        sheet_id = json_Data['data']['sheets'][0]['sheet_id']

        url = "	https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/" + sheet_token + "/values_batch_get?ranges=" + sheet_id + "!" + feishu_ranges
        Authorization_value="Bearer "+ user_access_token
        Content_Type = "application/json; charset=utf-8"
        payload = ''
        headers = {
            'Authorization': Authorization_value,
            'Content-Type': Content_Type
            }

        response = requests.request("GET", url, headers=headers, data=payload)
        json_Data = json.loads(response.text)
    except:
        with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
            f.write("user_access_token error or The SVN environment variable is not set" + '\n')
        progressbar.step(100)
        label_bar["text"] = str(round(progressbar["value"], 1)) + "%"
        window.update()
        time.sleep(0.05)
        return
    # print(json_Data)
    feishu_list = json_Data['data']['valueRanges'][0]['values']
    schedule = len(feishu_list)
    # print(feishu_list)
    for item in feishu_list:
        if 'link' in str(item) or 'text' in str(item):
            if item[0] != None:
                mid_module = item[0]
            module = mid_module + "\\" + item[1]

            svn_link = item[3]
            if type(svn_link) == list:
                with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a') as f:
                    f.write("The format of column F is incorrect------" + str(svn_link) + '\n')
                progressbar.step(float(1 / schedule) * 100)
                label_bar["text"] = str(round(progressbar["value"], 1)) + "%"
                window.update()
                time.sleep(0.05)
                continue
            try:
                feishu_link = item[2][0]['link']
            except:
                feishu_link = item[2][0]['text']
            # print(module)
            # print(feishu_link)
            # print(svn_link)
            link_class(user_access_token, module, svn_link, "", feishu_link)
            svn_Delete_Add(svn_link)
            svn_Import(str(os.path.dirname(app_path())) + "\\" + module, svn_link)

            shutil.rmtree(str(os.path.dirname(app_path())) + "\\" + mid_module)
        progressbar.step(float(1 / schedule) * 100)
        label_bar["text"] = str(round(progressbar["value"], 1)) + "%"
        window.update()
        time.sleep(0.05)
    
    print("OK")


window.mainloop()

